import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:kq_flutter_core_widget/utils/native/ble_native_util.dart';
import 'package:kq_flutter_core_widget/utils/toast_util.dart';
import 'package:kq_flutter_core_widget/widgets/button/kq_ink_well.dart';
import 'package:kq_flutter_widgets/resources/kq_theme_colors.dart';
import 'package:kq_flutter_widgets/utils/dialog_util.dart';
import 'package:kq_flutter_widgets/widgets/button/kq_small_button.dart';
import 'package:kq_flutter_widgets/widgets/divider/kq_divider.dart';
import 'package:kq_flutter_widgets/widgets/emptyView/empty_view.dart';
import 'package:kq_flutter_widgets/widgets/expandableList/kq_expand_group.dart';
import 'package:kq_flutter_widgets/widgets/formItem/entity/kq_form_entity.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_custom_item_view.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_header_item_view.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_switcher_item_view.dart';
import 'package:kq_flutter_widgets/widgets/tagView/kq_tag_view.dart';

/// 蓝牙demo
class BleDemo extends StatefulWidget {
  const BleDemo({Key? key}) : super(key: key);

  @override
  BleDemoState createState() => BleDemoState();
}

class BleDemoState extends State<BleDemo> {
  bool bleEnable = false;

  List<BleDevice> devices = [];

  bool isScanEnd = true;

  @override
  void initState() {
    super.initState();
    BleNativeUtil.isBleOpen().then((value) {
      if (value != null) {
        setState(() {
          bleEnable = value;
        });
      }
    });
    BleNativeUtil.listenBleEnable((enabled) {
      setState(() {
        bleEnable = enabled;
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
    BleNativeUtil.stopListenBleEnable(removeAll: true);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('蓝牙功能演示'),
      ),
      body: Column(
        children: [
          KqHeaderItemView(entity: KqFormEntity(title: "蓝牙状态监听")),
          KqSwitcherItemView(
              entity: KqFormEntity(
            title: "蓝牙开关状态",
            editable: false,
            checked: bleEnable,
          )),
          KqHeaderItemView(entity: KqFormEntity(title: "蓝牙开关(仅支持Android)")),
          KqCustomItemView(entity: KqFormEntity(
            customRightView: (entity) {
              return Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  KqSmallButton(
                    title: "打开蓝牙（仅Android可用）",
                    onTap: (disabled) {
                      BleNativeUtil.openBle();
                    },
                  ),
                  const SizedBox(
                    width: 20,
                  ),
                  KqSmallButton(
                    title: "关闭蓝牙(Android 12+失效)",
                    onTap: (disabled) {
                      BleNativeUtil.closeBle();
                    },
                  )
                ],
              );
            },
          )),
          KqHeaderItemView(entity: KqFormEntity(title: "搜索蓝牙")),
          KqCustomItemView(
              entity: KqFormEntity(
            title: "${devices.length}个蓝牙设备，结束$isScanEnd",
            customRightView: (entity) {
              return Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  KqSmallButton(
                    title: "开始搜索",
                    onTap: (disabled) {
                      setState(() {
                        devices.clear();
                      });
                      BleNativeUtil.startScanBle(
                        scanCallback: (isComplete, device) {
                          setState(() {
                            if (device != null && device.name != "NULL") {
                              devices.add(device);
                            }
                            isScanEnd = isComplete;
                          });
                        },
                      );
                    },
                  ),
                  const SizedBox(
                    width: 10,
                  ),
                  KqSmallButton(
                    title: "结束搜索",
                    onTap: (disabled) async {
                      var stopScanBle = await BleNativeUtil.stopScanBle();
                      if (stopScanBle != null) {
                        setState(() {
                          isScanEnd = stopScanBle;
                        });
                      }
                    },
                  )
                ],
              );
            },
          )),
          Expanded(
              child: devices.isEmpty
                  ? const KqEmptyView()
                  : ListView.builder(
                      itemCount: devices.length,
                      itemBuilder: (context, index) {
                        var device = devices[index];
                        // print("device.connectState=${device.connectState}");
                        // print("device.connectState?.getName()=${device.connectState?.getName()}");
                        return Column(
                          children: [
                            const KqDivider(
                              color: KqThemeColors.lineColor,
                              height: 6,
                            ),
                            KqInkWell(
                              horizontalPadding: 20,
                              verticalPadding: 8,
                              onTap: () {
                                connectDevice(device);
                              },
                              backgroundColor: Colors.white,
                              child: Column(
                                children: [
                                  Row(
                                    children: [
                                      Expanded(
                                          child: Text(device.name ?? "未知")),
                                      KqTagView(
                                        text: device.connectState?.getName() ??
                                            '',
                                        textColor: device.connectState ==
                                                BleConnectState.connected
                                            ? Colors.green
                                            : Colors.red,
                                      )
                                    ],
                                  ),
                                  const SizedBox(
                                    height: 20,
                                  ),
                                  Row(
                                    children: [
                                      Expanded(
                                          child: Text(device.macAddress ?? '')),
                                      Text('${device.rssi ?? 0}'),
                                    ],
                                  ),
                                ],
                              ),
                            ),
                            // 服务列表
                            ...(device.services
                                    ?.map((service) => Column(
                                          children: [
                                            const KqDivider(
                                              color: KqThemeColors.lineColor,
                                            ),
                                            KqExpandGroup(
                                                headerWidget: Row(
                                                  children: [
                                                    Text(
                                                      '${service.uuid} (${service.characters?.length ?? ""})',
                                                      style: const TextStyle(
                                                        fontSize: 14,
                                                      ),
                                                    ),
                                                  ],
                                                ),
                                                headerPaddingHorizontal: 20,
                                                headerExtraPaddingLeft: 0,
                                                childPaddingLeft: 0,
                                                childWidgets: [
                                                  /// 特征值列表
                                                  ...(service.characters
                                                          ?.map(
                                                              (character) =>
                                                                  Container(
                                                                    padding: const EdgeInsets
                                                                        .symmetric(
                                                                        horizontal:
                                                                            20,
                                                                        vertical:
                                                                            6),
                                                                    color: KqThemeColors
                                                                        .text59,
                                                                    child:
                                                                        Column(
                                                                      children: [
                                                                        Row(
                                                                          children: [
                                                                            Expanded(
                                                                                child: Text(
                                                                              '${character.uuid}',
                                                                              style: const TextStyle(fontSize: 14, color: Colors.white),
                                                                            )),
                                                                          ],
                                                                        ),
                                                                        if (character.extraData !=
                                                                            null)
                                                                          KqInkWell(
                                                                            onTap: () {
                                                                              Clipboard.setData(ClipboardData(text: toHexList(character.extraData, showHint: false)));
                                                                              KqToast.showSuccess("已复制到剪贴板");
                                                                            },
                                                                            child: Container(
                                                                              color:
                                                                                  Colors.yellowAccent,
                                                                              margin:
                                                                                  const EdgeInsets.only(top: 8, bottom: 8),
                                                                              padding:
                                                                                  const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
                                                                              child:
                                                                                  Row(
                                                                                children: [
                                                                                  Expanded(
                                                                                      child: Text(
                                                                                    toHexList(character.extraData),
                                                                                    style: const TextStyle(fontSize: 15, fontFamily: 'Courier New'),
                                                                                  )),
                                                                                ],
                                                                              ),
                                                                            ),
                                                                          ),
                                                                        if (device.connectState ==
                                                                            BleConnectState.connected)
                                                                          Container(
                                                                            margin:
                                                                                const EdgeInsets.only(top: 6),
                                                                            child:
                                                                                Row(
                                                                              children: [
                                                                                KqSmallButton(
                                                                                  title: "Notify开",
                                                                                  onTap: (disabled) async {
                                                                                    bool? notify = await BleNativeUtil.notify(
                                                                                      device: device,
                                                                                      service: service.uuid ?? '',
                                                                                      character: character.uuid ?? '',
                                                                                      callback: (service, character1, data) {
                                                                                        print(data);
                                                                                        KqToast.showSuccess("收到${character1}的数据，长度${data.length}");
                                                                                        setState(() {
                                                                                          character.extraData = data;
                                                                                        });
                                                                                      },
                                                                                    );
                                                                                    if (notify != null && notify) {
                                                                                      KqToast.showSuccess("Notify已打开");
                                                                                    } else {
                                                                                      KqToast.showSuccess("Notify打开失败");
                                                                                    }
                                                                                  },
                                                                                ),
                                                                                const SizedBox(
                                                                                  width: 20,
                                                                                ),
                                                                                KqSmallButton(
                                                                                  title: "Notify关",
                                                                                  onTap: (disabled) async {
                                                                                    bool? notify = await BleNativeUtil.unNotify(device: device, service: service.uuid ?? '', character: character.uuid ?? '');
                                                                                    if (notify != null && notify) {
                                                                                      KqToast.showSuccess("Notify已关闭");
                                                                                    }
                                                                                  },
                                                                                ),
                                                                                const SizedBox(
                                                                                  width: 20,
                                                                                ),
                                                                                KqSmallButton(
                                                                                  title: "写入数据",
                                                                                  onTap: (disabled) async {
                                                                                    KqDialog.showInputDialog(
                                                                                      "写入数据",
                                                                                      defValue: "55 33 01 3E b1 27",
                                                                                      onConfirm: (value) async {
                                                                                        List<int> data = hexStringToBytes(value);
                                                                                        var writeOk = await BleNativeUtil.writeCharacterData(device: device, service: service.uuid ?? '', character: character.uuid ?? '', value: data);
                                                                                        if (writeOk != null && writeOk) {
                                                                                          KqToast.showSuccess("写入成功");
                                                                                        }
                                                                                      },
                                                                                    );
                                                                                  },
                                                                                ),
                                                                              ],
                                                                            ),
                                                                          )
                                                                      ],
                                                                    ),
                                                                  ))
                                                          .toList()) ??
                                                      []
                                                ])
                                          ],
                                        ))
                                    .toList() ??
                                [])
                          ],
                        );
                      },
                    ))
        ],
      ),
    );
  }

  List<int> hexStringToBytes(String hexString) {
    List<String> hexValues = hexString.split(' ');
    List<int> byteList = [];

    for (String hex in hexValues) {
      int decimalValue = int.parse(hex, radix: 16);
      byteList.add(decimalValue);
    }

    return byteList;
  }

  void connectDevice(BleDevice device) async {
    if (device.connectState == BleConnectState.connected) {
      await BleNativeUtil.disConnectDevice(device: device);
      return;
    }
    KqDialog.showLoading(msg: "正在连接...");
    BleConnectResult? result = await BleNativeUtil.connectDevice(
      device: device,
      stateCallback: (macAddress, connectState) {
        print("connectState=$connectState");
        if (device.connectState != connectState) {
          KqToast.showNormal("蓝牙${connectState.getName()}");
          setState(() {
            device.connectState = connectState;
          });
        }
      },
    );
    KqDialog.closeLoading();
    if (result == null || result.connectState != BleConnectState.connected) {
      KqToast.showNormal("连接失败");
    } else {
      print(result);
      setState(() {});
      KqToast.showSuccess("连接成功");
    }
  }

  String toHexList(List<int> byteList, {bool showHint = true}) {
    StringBuffer buffer = StringBuffer();

    int count = byteList.length ~/ 10;
    for (int i = 0; i < byteList.length; i += 10) {
      // 获取当前要处理的10个字节
      List<int> sublist = byteList.sublist(
          i, i + 10 < byteList.length ? i + 10 : byteList.length);

      // 将10个字节转换为十六进制字符串
      String hexString = sublist.map((int byte) {
        return byte.toRadixString(16).padLeft(2, '0');
      }).join(' ');

      // 将十六进制字符串追加到 buffer
      buffer.write(hexString);

      if (showHint) {
        buffer.write("($i~${i + 9})");
      }

      // 换行
      if (i ~/ 10 < count) {
        buffer.writeln();
      }
    }

    // 返回最终的字符串
    return buffer.toString();
  }
}
